home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / U-Z / YACC / yypars.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-05  |  7.2 KB  |  332 lines  |  [TEXT/KAHL]

  1. /*
  2.   HEADER: CUG     nnn.nn;
  3.   TITLE:     YACC - Yet Another Compilier-Compilier
  4.   VERSION:     1.0 for IBM-PC
  5.   DATE:      JAN 28, 1985
  6.   DESCRIPTION:     LALR(1) Parser Generator. From UNIX
  7.   KEYWORDS:     Parser Generator Compilier-Compilier YACC
  8.   SYSTEM:     IBM-PC and Compatiables
  9.   FILENAME:        YYPARS.C
  10.   WARNINGS:     This program is not for the casual user. It will
  11.          be useful primarily to expert developers.
  12.   CRC:         N/A
  13.   SEE-ALSO:     LEX and PREP
  14.   AUTHORS:     Scott Guthery 11100 leafwood lane Austin, TX 78750
  15.   COMPILERS:     DESMET-C
  16.   REFERENCES:     UNIX Systems Manuals
  17.   Adapted for the Mac 90/04/13 and after, Maarten Meijer
  18. */
  19. # ifndef YYMAXDEPTH
  20. # define YYMAXDEPTH 150
  21. # endif
  22.  
  23. /* # define    __UNION__ */    /* allow UNION asignment */
  24.  
  25. # define YYFLAG        (-1000)
  26. # define YYERROR    goto yyerrlab
  27. # define YYACCEPT    return(0)
  28. # define YYABORT    return(1)
  29.  
  30. #define    YYWAS0ERR    0
  31. #define    YYWAS1ERR    1
  32. #define    YYWAS2ERR    2
  33. #define    YYWAS3ERR    3
  34.  
  35. #ifdef    THINK_C
  36. void yyinit(void);    /* prototype to be called at startup */
  37. #endif
  38.  
  39. /*        parser for yacc output  */
  40.  
  41. # ifdef    YYDEBUG
  42. int yydebug = 0;        /* 1 for debugging */
  43. # endif
  44.  
  45. static    YYSTYPE *yyv = NULL;    /* [YYMAXDEPTH]; /* where the values are stored */
  46. static    int yychar = -1;        /* current input token number */
  47. static    int yynerrs = 0;        /* number of errors */
  48. static    short yyerrflag = 0;    /* error recovery flag */
  49. static    short *yys = NULL;                /* [YYMAXDEPTH]; */
  50.  
  51. yyparse()
  52.     {
  53.  
  54. /*    short yys[YYMAXDEPTH];    */    /* allocate instead to reduce stack usage */
  55.     short yyj, yym;
  56.     register YYSTYPE *yypvt;
  57.     register short yystate, *yyps, yyn;
  58.     register YYSTYPE *yypv;
  59.     register short *yyxi;
  60.     if(yyv == NULL) {
  61.         yyv = (YYSTYPE *) calloc (YYMAXDEPTH, sizeof(YYSTYPE));
  62.         if(yyv == NULL)
  63.             {
  64.             yyerror( "yacc no space for yyv[] vector" );
  65.             return(1);
  66.             }
  67.         }
  68.     if(yys == NULL) {
  69.         yys = (short *) calloc (YYMAXDEPTH, sizeof(short));
  70.         if(yys == NULL)
  71.             {
  72.             yyerror( "yacc no space for yys[] vector" );
  73.             return(1);
  74.             }
  75.         }
  76. #ifdef    YACC_RESOURCES
  77.     yyinit();
  78. #endif
  79.     yystate = 0;
  80.     yychar = -1;
  81.     yynerrs = 0;
  82.     yyerrflag = 0;
  83.     yyps= &yys[-1];
  84.     yypv= &yyv[-1];
  85.  
  86. yystack:     /* put a state and value onto the stack */
  87.  
  88. # ifdef    YYDEBUG
  89.     if( yydebug  ) {
  90.         if( ! ((yystate == 0) && (yychar == -1)))
  91.             printf( "state %d, next token %d == '%c'\n",
  92.                 yystate,
  93.                 yychar,
  94.                 isprint(yychar) ? yychar : '◊');
  95.         }
  96. # endif
  97.     if( ++yyps> &yys[YYMAXDEPTH] )
  98.         {
  99.         yyerror( "yacc stack overflow" );
  100.         return(1);
  101.         }
  102.     *yyps = yystate;
  103.     ++yypv;
  104. # ifdef __UNION__
  105.     yyunion(yypv, &yyval);
  106. # else
  107.     *yypv = yyval;
  108. # endif
  109. yynewstate:
  110.  
  111.     yyn = yypact[yystate];
  112.  
  113.     if( yyn<= YYFLAG )
  114.         goto yydefault; /* simple state */
  115.  
  116.     if( yychar<0 )
  117.         if( (yychar=yylex())<0 )
  118.             yychar=0;
  119.     if( (yyn += yychar)<0 || yyn >= YYLAST )
  120.         goto yydefault;
  121.  
  122.     if( yychk[ yyn=yyact[ yyn ] ] == yychar )
  123.         {
  124.         /* valid shift */
  125.         yychar = -1;
  126. # ifdef __UNION__
  127.           yyunion(&yyval, &yylval);
  128. # else
  129.         yyval = yylval;
  130. # endif
  131.         yystate = yyn;
  132.         if( yyerrflag > 0 )
  133.             --yyerrflag;
  134.         goto yystack;
  135.         }
  136. yydefault:
  137.     /* default state action */
  138.  
  139.     if( (yyn=yydef[yystate]) == -2 )
  140.         {
  141.         if( yychar<0 )
  142.             if( (yychar=yylex())<0 )
  143.                 yychar = 0;
  144.         /* look through exception table */
  145.         for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 )
  146.             ; /* VOID */
  147.  
  148.         for(yyxi+=2; *yyxi >= 0; yyxi+=2)
  149.             {
  150.             if( *yyxi == yychar )
  151.                 break;
  152.             }
  153.         if( (yyn = yyxi[1]) < 0 )
  154.             return(0);    /* accept */
  155.         }
  156.  
  157.     if( yyn == 0 )
  158.         {
  159.         /* error */
  160.         /* error ... attempt to resume parsing */
  161.  
  162.         switch( yyerrflag )
  163.             {
  164.  
  165.         case YYWAS0ERR:    /* brand new error */
  166.  
  167.             yyerror( "syntax error" );
  168. yyerrlab:
  169.             ++yynerrs;
  170.         case YYWAS1ERR:
  171.         case YYWAS2ERR: /* incompletely recovered error ... try again */
  172.  
  173.             yyerrflag = 3;
  174.  
  175.             /* find a state where "error" is a legal shift action */
  176.  
  177.             while ( yyps >= yys )
  178.                 {
  179.                 yyn = yypact[*yyps] + YYERRCODE;
  180.                 if( yyn>= 0 && yyn < YYLAST &&
  181.                     yychk[yyact[yyn]] == YYERRCODE )
  182.                     {
  183.                     yystate = yyact[yyn];  /* simulate a shift of "error" */
  184.                     goto yystack;
  185.                     }
  186.                 yyn = yypact[*yyps];
  187.  
  188.                 /* the current yyps has no shift onn "error", pop stack */
  189.  
  190. # ifdef    YYDEBUG
  191.                 if( yydebug )
  192.                     printf( "error: pops state %d, recover state %d\n",
  193.                         *yyps,
  194.                         yyps[-1] );
  195. # endif
  196.                 --yyps;
  197.                 --yypv;
  198.                 }
  199.  
  200.             /* there is no state on the stack with an error shift ... abort */
  201.  
  202. yyabort:
  203.             return(1);
  204.  
  205.  
  206.         case YYWAS3ERR:  /* no shift yet; clobber input char */
  207.  
  208. # ifdef    YYDEBUG
  209.             if( yydebug )
  210.                 printf( "error: discards token %d\n", yychar );
  211. # endif
  212.  
  213.             if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */
  214.             yychar = -1;
  215.             goto yynewstate;    /* try again in the same state */
  216.  
  217.             }
  218.  
  219.         }
  220.  
  221.     /* reduction by production yyn */
  222.  
  223. # ifdef    YYDEBUG
  224.     if( yydebug ) printf("reduce with rule %d\n",yyn);
  225. # endif
  226.     yyps -= yyr2[yyn];
  227.     yypvt = yypv;
  228.     yypv -= yyr2[yyn];
  229. # ifdef __UNION__
  230.     yyunion(&yyval, &yypv[1]);
  231. # else
  232.     yyval = yypv[1];
  233. # endif
  234.     yym=yyn;
  235.     /* consult goto table to find next state */
  236.     yyn = yyr1[yyn];
  237.     yyj = yypgo[yyn] + *yyps + 1;
  238.     if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn )
  239.         yystate = yyact[yypgo[yyn]];
  240.     switch(yym)
  241.         {
  242.         $A
  243.         }
  244.     goto yystack;  /* stack new state and value */
  245.     }
  246.  
  247. #ifdef    THINK_C
  248. #ifdef    YACC_RESOURCES
  249. /*
  250.  *    Use this to set up the parser tables from resources instead of the
  251.  *    global space (precious at 32K max size). MM 90/04/16
  252.  */
  253.  
  254. static    setup_yacc_res(short **tab, char *pname);
  255.  
  256. static    setup_yacc_res(short **tab, char *pname) {
  257.     short    **h;
  258. /*
  259.  *    Not that using Get1NamedResource will produce errors when debugging
  260.  *    with THINK C, since the project resource file is opened after the
  261.  *    project itself, but I consider this a safer call. MM 90/04/16
  262.  */
  263.     h = (short **)Get1NamedResource(YACC_RESTYPE, pname);
  264.     if(h == NULL)
  265.         Debugger();
  266. /*
  267.  *    to move them out of the way, another possibility is to allocate
  268.  *    a pointer and copy the information wuith a BlockMove();
  269.  */
  270.     DetachResource(h);
  271.     MoveHHi(h);
  272.     HLock(h);
  273.     HNoPurge(h);
  274.     /* set up the pointer */
  275.     *tab = *h;
  276.     }
  277. #endif
  278.  
  279. /*    This function is called by llinit() in LEXLIB, to initialize
  280.  *    yylval to zero, and also by yyparse() if using resources for
  281.  *    the tables.
  282.  */
  283. void yyinit() {
  284.     int    i, j;
  285.     char    *p;
  286. #ifdef    YACC_RESOURCES
  287.     short    saveResFile, saveVol;
  288. #ifndef    YACC_ALONE
  289.     short    yResFile;
  290. #endif
  291. #endif
  292.  
  293.     /* set yylval to zero */
  294.     i = sizeof(YYSTYPE);
  295.     for(j = i, p = (char *)&yylval; j; j--, p++)
  296.         *p = '\0';
  297.  
  298.     /* initialize the tables */
  299. #ifdef    YACC_RESOURCES
  300.     if(yydef == 0L) {    /* check only one */
  301.         /* save the state of things */
  302.         GetVol(0L, &saveVol);
  303.         saveResFile = CurResFile();
  304. #ifdef    YACC_ALONE
  305. /*        UseResFile(CurApRefNum);    /* will not work when debugging */
  306.                                     /* with THINK C, since the project */
  307.                                     /* resource file is opened after */
  308.                                     /* the project itself. Better to */
  309.                                     /* uncomment this when doing the */
  310.                                     /* final build. MM 90/04/16 */
  311. #else
  312.         yResFile = OpenResFile(YACC_RESFILENAME);
  313.         UseResFile(yResFile);
  314. #endif
  315.         setup_yacc_res(&yyact,    "\pyyact");
  316.         setup_yacc_res(&yypact,    "\pyypact");
  317.         setup_yacc_res(&yypgo,    "\pyypgo");
  318.         setup_yacc_res(&yyr1,    "\pyyr1");
  319.         setup_yacc_res(&yyr2,    "\pyyr2");
  320.         setup_yacc_res(&yychk,    "\pyychk");
  321.         setup_yacc_res(&yydef,    "\pyydef");
  322. #ifndef    YACC_ALONE
  323.         CloseResFile(yResFile);
  324. #endif
  325.         /* restore the state of things */
  326.         UseResFile(saveResFile);
  327.         SetVol(0L, saveVol);
  328.         }
  329. #endif
  330.     }
  331. #endif
  332.